﻿
package extremefx.events {
	import extremefx.IDisposable;	

	/**
	 * @author Marcelo Volmaro
	 */
	public final class EventHandler implements IDisposable {
		private var _handlers:Vector.<Function>;
		private var _target:Object;
		
		/**
		 * Creates a new instance of an Event Handler
		 * @param pTarget the target object
		 */
		public function EventHandler(pTarget:Object) {
			_handlers = new Vector.<Function>();
			_target = pTarget;
		}
		
		/**
		 * Adds a suscriber to the event handler
		 * @param pSuscriber The suscriber to be added-
		 * @param pArgs An optional Array of arguments. 
		 */
		public function add(pSuscriber:Function):void {
			if (!_handlers) return;
			remove(pSuscriber);// Just in case...
			_handlers.push(pSuscriber);
		}
		
		/**
		 * Removes a suscriber from the event handler list
		 * @param pSuscriber The suscriber to remove,
		 */
		public function remove(pSuscriber:Function):void {
			if (!_handlers) return;
			
			var idx:int = _handlers.indexOf(pSuscriber);
			if (idx != -1) _handlers.splice(idx, 1);
		}
		
		/**
		 * Fires an event to all suscribers
		 * @param pArgs An optional Array of arguments. 
		 */
		public function fire(pArgs:EventArgs = null):void{
			if (!_handlers) return;
			
			if (pArgs == null){
				pArgs = new EventArgs();
			}
			
			//create a copy, so if an event handlers modifies the event list, that modification does not gets
			//propagated until next firing...
			var s:Vector.<Function> = _handlers.concat(),
			t:Object = _target;

			var l:uint = s.length, i:uint = 0;
			while (i < l){ 
				s[i++](t, pArgs);
			}
		}
		
		public function dispose():void {
			_handlers = null;
			_target = null;
		}
	}
}